package com.ericsson.enap.modules.ebmLog.service.impl;

import com.ericsson.common.util.LogFileName;
import com.ericsson.common.util.LoggerUtils;
import com.ericsson.enap.modules.ebmLog.utils.EbmDimensionUtil;
import com.ericsson.enap.modules.ebmLog.utils.EbmLogUtil;
import com.ericsson.enap.modules.ebmLog.constant.EbmConstant;
import com.ericsson.enap.modules.ebmLog.entity.*;
import com.ericsson.enap.modules.ebmLog.service.EbmEventService;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.IndexModel;
import jodd.bean.BeanUtil;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: ebm单个事件处理实现类
 * @author: wangjingshi
 * @create: 2021-04-21 14:33
 */
@Service
public class EbmAttServiceImpl implements EbmEventService {

    private Logger log = LoggerUtils.Logger(LogFileName.EbmLogJob);

    private Map<String,Map<String,EbmStatisticMapVO>>  dimensionMap = new HashMap<>();

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void executeEvent(String localPath,String dateTime,String netid,String event_type,String event_name) {
        Map<String,EbmStatisticMapVO> map;
        //初始化统计维度数组
        for (String dimensionKey:EbmConstant.att) {
            map = new HashMap<>();
            dimensionMap.put(dimensionKey,map);
        }
        try {
            File file = new File(localPath+event_type+".log");
            if(file.exists()){
                InputStreamReader read = new InputStreamReader(new FileInputStream(localPath+event_type+".log"));
                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt;
                String cclineTxt;
                EbmVO ebmVo = null;
                boolean isContinue = false;// 是否跳过
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    if (lineTxt.indexOf("====EVENT====") > -1) {
                        ebmVo = new EbmVO();
                        isContinue = false;// 不跳过
                        continue;
                    }
                    if (isContinue) {
                        continue;
                    }
                    if (lineTxt.trim().indexOf("event_result") == 0 ) {
                        EbmDimensionUtil.setEvent_result(lineTxt, ebmVo);
                        continue;
                    }else if (lineTxt.trim().indexOf("attach_type") == 0) {
                        EbmDimensionUtil.setAttach_type(lineTxt, ebmVo);
                        continue;
                    }else if (lineTxt.trim().indexOf("l_cause_prot_type") == 0) {
                        cclineTxt = bufferedReader.readLine();
                        //防止 cause_code = CAUSE_CODE 这种情况
                        if(cclineTxt.contains("cause_code = CAUSE_CODE")){
                            isContinue = true;
                            continue;
                        }
                        EbmDimensionUtil.setCcScc(bufferedReader, cclineTxt, ebmVo);
                    } else if (lineTxt.trim().indexOf("tai") == 0) {
                        EbmDimensionUtil.setTaiAndTac(bufferedReader, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("mmei") == 0)	{
                        EbmDimensionUtil.setMmei(bufferedReader, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("eci") == 0) {
                        EbmDimensionUtil.setEciAndEnodeb(lineTxt, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("target_lai") == 0) {
                        EbmDimensionUtil.setLai(bufferedReader, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("imsi") == 0) {
                        EbmDimensionUtil.setImsiseriesAndImsi(lineTxt, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("imeisv") == 0) {
                        EbmDimensionUtil.setImeitac(lineTxt, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("apn") == 0) {
                        EbmDimensionUtil.setApn(lineTxt, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("s_gw") == 0) {
                        EbmDimensionUtil.setSgw(bufferedReader, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("p_gw") == 0) {
                        EbmDimensionUtil.setPgw(bufferedReader, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("msc") == 0) {
                        EbmDimensionUtil.setMsc(bufferedReader, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("msisdn") == 0) {
                        EbmDimensionUtil.setMsisdn(lineTxt, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("nas_esm_cause_code") == 0) {
                        EbmDimensionUtil.setNasesmcausecode(lineTxt, ebmVo);
                        continue;
                    } else if (lineTxt.trim().indexOf("ue_requested_apn") == 0) {
                        ebmVo.setNetid(netid);
                        ebmVo.setDateTime(dateTime);
                        statisticAndBuildMap(ebmVo,dimensionMap);
                    }
                }
                bufferedReader.close();
                read.close();
            }
        } catch (Exception e) {
            log.info(" ===== Exception EbmAttServiceImpl executeEvent "+e.getMessage(),e);
            e.printStackTrace();
        }
        insertMongoDB(event_name,dateTime,netid);
    }

    private void insertMongoDB(String event_name,String dateTime,String netid) {
        String tableDateTime = dateTime.substring(0, 10).replaceAll("-", "_");
        String collectionName = tableDateTime + "_"+event_name+"_ebmlog_statistics";
        System.out.println("=========collectionName======"+collectionName);
        if(!mongoTemplate.collectionExists(collectionName)){
            List<IndexModel> indexModelList = new ArrayList<>();
            BasicDBObject index = new BasicDBObject();
            index.put("netid",1);
            index.put("dateTime",1);
            index.put("ccscc",1);
            indexModelList.add(new IndexModel(index));
            mongoTemplate.createCollection(collectionName).createIndexes(indexModelList);
        }
        //遍历map,生成中间的middleList,为后续按照ccScc分组做准备
        List<EbmStatisticMapVO> middleList = new ArrayList<>();
        for (Map.Entry<String,Map<String,EbmStatisticMapVO>> entry : dimensionMap.entrySet()) {
            List<EbmStatisticMapVO> _list = entry.getValue().values().stream().collect(Collectors.toList());
            middleList.addAll(_list);
        }
        //key:ccScc,inner_key:各种维度
        Map<String,Map<String,List<EbmStatisticMapVO>>> mp = middleList.stream()
                .collect(Collectors.groupingBy(EbmStatisticMapVO::getCcScc,Collectors.groupingBy(EbmStatisticMapVO::getK_name)));

        List<EbmMongoVO> mlist = new ArrayList<>();
        for (Map.Entry<String,Map<String,List<EbmStatisticMapVO>>> outerEntry : mp.entrySet()) {
            EbmMongoVO outer = new EbmMongoVO();
            String ccScc = outerEntry.getKey();
            outer.setCcScc(ccScc);
            outer.setNetid(netid);
            outer.setDateTime(dateTime);
            outer.setCc(ccScc.split("-")[0]);
            outer.setScc(ccScc.split("-")[1]);
            int _index = 0;
            for(Map.Entry<String,List<EbmStatisticMapVO>> innerEntry: outerEntry.getValue().entrySet()){
                _index++;
                BeanUtil.pojo.setProperty(outer, innerEntry.getKey(), innerEntry.getValue());
                if(_index == 1){
                    outer.setCcDesc(innerEntry.getValue().get(0).getCcDesc());
                    outer.setSccDesc(innerEntry.getValue().get(0).getSccDesc());
                }
            }
            mlist.add(outer);
        }
        mongoTemplate.insert(mlist,collectionName);
    }

    private void statisticAndBuildMap(EbmVO ebmVo,Map<String,Map<String,EbmStatisticMapVO>>  dimensionMap) {
        for (Map.Entry<String,Map<String,EbmStatisticMapVO>> entry : dimensionMap.entrySet()) {
            EbmLogUtil.doMmeStatisticAndBuildMap(ebmVo,entry.getValue(),
                    BeanUtil.pojo.getProperty(ebmVo, entry.getKey()).toString(),entry.getKey());
        }
    }



}
